package com.zjuh.goodboy.claw;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zjuh.goodboy.misc.HttpCodes;
import com.zjuh.goodboy.util.IoUtil;
import com.zjuh.goodboy.util.StringUtil;

public class JavaClawer implements Clawer {

	private static final String DEFAULT_CHARSET = "utf-8";
	
	private static final Logger log = LoggerFactory.getLogger(JavaClawer.class);
	
	private String userAgent = " Mozilla/5.0 (Windows NT 6.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1";
	
	private int timeout = 2000;
	
	@Override
	public ClawerResult claw(String url) {
		ClawerResult result = new ClawerResult(false);
		InputStream is = null;
		try {
			URL urlObject = new URL(url);
			HttpURLConnection conn = (HttpURLConnection)urlObject.openConnection();
			
			conn.setConnectTimeout(timeout);
			conn.setReadTimeout(timeout);
			
			// request
			conn.setRequestProperty("User-Agent", userAgent);
			
			// response
			int code = conn.getResponseCode();
			result.setCode(code);
			if (code != HttpCodes.SUCCESS) {
				return result;
			}
			is = conn.getInputStream();
			String charset = getCharset(conn);
			if (StringUtil.isEmpty(charset)) {
				charset = DEFAULT_CHARSET;
			}
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			IoUtil.copy(is, os);
			
			result.setData(os.toString(charset));
			result.setSuccess(true);
			log.info("finish claw: " + url);
		}catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			IoUtil.closeQuietly(is);
		}
		return result;
	}
	
	private String getCharset(HttpURLConnection conn) {
		String charset = conn.getContentEncoding();
		if (!StringUtil.isEmpty(charset)) {
			return charset;
		}
		String contentType = conn.getContentType();
		charset = getCharsetFromContentType(contentType);
		if (!StringUtil.isEmpty(charset)) {
			return charset;
		}
		return DEFAULT_CHARSET;
	}
	
	private static String getCharsetFromContentType(String contentType) {
		if (StringUtil.isEmpty(contentType)) {
			return null;
		}
		String charsetKV = getAfterString(contentType, ";");
		if (StringUtil.isEmpty(charsetKV)) {
			return null;
		}
		String name = StringUtil.trimToEmpty(getBeforeString(charsetKV, "="));
		String value = StringUtil.trimToEmpty(getAfterString(charsetKV, "="));
		if ("charset".equals(name.toLowerCase())) {
			return value;
		}
		return null;
	}
	
	private static String getAfterString(String input, String token) {
		if (StringUtil.isEmpty(input)) {
			return null;
		}
		int pos = input.indexOf(token);
		if (pos < 0) {
			return null;
		}
		return input.substring(pos + 1);
	}
	
	private static String getBeforeString(String input, String token) {
		if (StringUtil.isEmpty(input)) {
			return null;
		}
		int pos = input.indexOf(token);
		if (pos < 0) {
			return null;
		}
		return input.substring(0, pos);
	}

}
